﻿//
//Description : Classe de collection d'entité
//Auteur : Marc-Eric Boisvert
//Date Création : 31 mars 2008
//Révisions:
//

using System;
using System.Collections.Generic;

namespace Framework.Data.Core
{

    [Serializable()]
    public class EntityCollection<TKey, TValue> : Dictionary<TKey, TValue>, IEntityCollection<TKey, TValue> where TValue : IBaseEntity
    {

        #region "Membres"

        //Type des entités de la collection
        protected Type _entityType;
        #endregion
        protected string _sortOrder = string.Empty;

        #region "Construteurs"

        /// <summary>
        /// Constructeur
        /// </summary>
        /// <remarks></remarks>
        public EntityCollection()
            : base()
        {
            this._entityType = typeof(TValue);
        }

        /// <summary>
        /// Constructeur
        /// </summary>
        /// <param name="entityType">Type des entités</param>
        /// <remarks></remarks>
        public EntityCollection(System.Type entityType)
            : base()
        {
            this._entityType = entityType;
        }

        #endregion

        #region "IEntityCollection"

        /// <summary>
        /// Procédure qui permet d'ajouter un entité à la collection
        /// </summary>
        /// <param name="key">Clé</param>
        /// <param name="baseEntity">L'entité à ajouter</param>
        /// <remarks></remarks>
        public new void Add(TKey key, TValue baseEntity)
        {
            base.Add(key, baseEntity);
        }

        public new int Count
        {
            get { return base.Count; }
        }

        public System.Type EntityType
        {
            get { return this._entityType; }
        }

        /// <summary>
        /// Fonction qui permet d'enlever un entité à la collection
        /// </summary>
        /// <param name="key">Clé</param>
        /// <returns>Boolean</returns>
        /// <remarks></remarks>
        public new bool Remove(TKey key)
        {
            return base.Remove(key);
        }

        /// <summary>
        /// Fonction qui converti la collection en IList
        /// </summary>
        /// <returns>IList</returns>
        /// <remarks></remarks>
        public ListObject[] ToListObject(string displayFieldName)
        {
            return this.ToListObject(displayFieldName, true);
        }

        /// <summary>
        /// Fonction qui converti la collection en IList
        /// </summary>
        /// <param name="displayFieldName">Champ qui sera affiché</param>
        /// <param name="sortList">Indique si la liste doit être triée</param>
        /// <returns>IList</returns>
        /// <remarks></remarks>
        public ListObject[] ToListObject(string displayFieldName, bool sortList)
        {
            ListObject[] entityList = new ListObject[this.Count];
            Int32 i = 0;
            foreach (TValue entity in this.Values)
            {
                entityList.SetValue(new ListObject(entity.GetPrimaryKeyField().Value, entity.GetField(displayFieldName).Value.ToString(), entity), i);
                i = i + 1;
            }
            if (sortList)
            {
                //On tri la liste
                Array.Sort(entityList, new ListObjectComparer());
            }

            return entityList;
        }

        /// <summary>
        /// Fonction qui converti la collection en IList
        /// </summary>
        /// <param name="displayFieldsName">Champs qui sera affiché séparé par une virgule. Ex: "Nom, Description"</param>
        /// <param name="seperator">Chaîne utilisé pour séparé les champs lors de l'affichage</param>
        /// <param name="sortList">Indique si la liste doit être triée</param>
        /// <returns>IList</returns>
        /// <remarks></remarks>
        public ListObject[] ToListObject(string displayFieldsName, string seperator, bool sortList)
        {
            ListObject[] entityList = new ListObject[this.Count];
            string[] fields = displayFieldsName.Split(',');
            string value = null;
            Int32 i = 0;
            foreach (TValue entity in this.Values)
            {
                value = "";
                for (int j = 0; j <= fields.Length - 1; j++)
                {
                    value += ((IListField)entity.GetField(fields[j])).DisplayText;
                    if (j < fields.Length - 1)
                    {
                        value += seperator;
                    }
                }
                entityList.SetValue(new ListObject(entity.GetPrimaryKeyField().Value, value, entity), i);
                i = i + 1;
            }
            if (sortList)
            {
                //On tri la liste
                Array.Sort(entityList, new ListObjectComparer());
            }

            return entityList;
        }

        /// <summary>
        /// Fonction qui copy la collection dans un array list
        /// </summary>
        /// <returns>List(Of TValue)</returns>
        /// <remarks></remarks>
        public System.Collections.Generic.List<TValue> ToArrayList()
        {
            List<TValue> arrayList = new List<TValue>();
            foreach (TValue entity in this.Values)
            {
                arrayList.Add(entity);
            }

            return arrayList;
        }

        public string SortOrder
        {
            get { return this._sortOrder; }
            set { this._sortOrder = value; }
        }
        #endregion

        #region "Événements"
        public event EntityAddedEventHandler EntityAdded;
        public delegate void EntityAddedEventHandler(object sender, IBaseEntity e);
        public event EntityRemovedEventHandler EntityRemoved;
        public delegate void EntityRemovedEventHandler(object sender, IBaseEntity e);
        #endregion

    }
}